#include "OmPublic.h"
#include "OmLog.h"

namespace OmPublic
{
//	static LogManager logManager;

	Log::Log(const String & name, bool debug) :
		mName(name), mOnlyDebug(debug)
	{
		mfpLog.open(mName.c_str());
	}

	Log::~Log()
	{
		OM_LOCK_AUTO_MUTEX
		mfpLog.close();
	}

	void Log::logMessage(const String & message, LogLevel ll, bool maskDebug)
	{
		OM_LOCK_AUTO_MUTEX
		for (LogListeners::iterator i = mLogListeners.begin(); i != mLogListeners.end(); ++i)		
			(*i)->messageLogged(message, ll, maskDebug, mName);			
		
		struct tm *pTime;
		time_t ctTime; time(&ctTime);
		pTime = localtime( &ctTime );
		
		mfpLog << std::setw(2) << std::setfill(L'0') << pTime->tm_hour
			<< L":" << std::setw(2) << std::setfill(L'0') << pTime->tm_min
			<< L":" << std::setw(2) << std::setfill(L'0') << pTime->tm_sec 
			<< L" " << message.c_str() << std::endl;

		// Flush stcmdream to ensure it is written (incase of a crash, we need log to be up to date)
		mfpLog.flush();
	}

	LogManager::LogManager()
	{
		mDefaultLog = 0;
	}

	LogManager::~LogManager()
	{
		OM_LOCK_AUTO_MUTEX
		LogList::iterator i;
		for (i = mLogs.begin(); i != mLogs.end(); ++i)
		{
			OM_DELETE i->second;
		}
	}

	Log* LogManager::createLog(const String & name, bool defaultLog /* = false */, bool debug /* = true */)
	{
		OM_LOCK_AUTO_MUTEX
		Log* newLog= OM_NEW Log(name, debug);
		if (!mDefaultLog || defaultLog)
		{
			mDefaultLog=newLog;
		}
		mLogs.insert(LogList::value_type(name.c_str(), newLog));
		return newLog;
	}

	Log* LogManager::getLog(const OmPublic::String &name)
	{
		OM_LOCK_AUTO_MUTEX
		LogList::iterator i = mLogs.find(name.c_str());
		if (i != mLogs.end())
			return i->second;
		else
			OM_EXCEPT(Exception::ERR_INVALIDPARAMS, "Log not found. ", "LogManager::getLog");
	}

	Log* LogManager::getDefaultLog()
	{
		OM_LOCK_AUTO_MUTEX
		return mDefaultLog;
	}
	
	Log* LogManager::setDefaultLog(Log* log)
	{
		OM_LOCK_AUTO_MUTEX
		Log* oldLog = mDefaultLog;
		mDefaultLog = log;
		return oldLog;
	}

	void LogManager::destroyLog(Log* log)
	{
		destroyLog(log->getName());
	}

	void LogManager::destroyLog(const String & name)
	{
		OM_LOCK_AUTO_MUTEX
		LogList::iterator i = mLogs.find(name.c_str());
		if (i != mLogs.end())
		{
			if (mDefaultLog == i->second)
			{
				mDefaultLog = 0;
			}
			OM_DELETE i->second;
			mLogs.erase(i);
		}

		if (!mDefaultLog && !mLogs.empty())
		{
			mDefaultLog = mLogs.begin()->second;
		}
	}

	void LogManager::logMessage(const String & message, Log::LogLevel ll /* = Log::LL_NORMAL */, bool debug /* = true */)
	{
		OM_LOCK_AUTO_MUTEX
		if (mDefaultLog)
		{
			mDefaultLog->logMessage(message, ll, debug);
		}
	}
	
}
